%{
#undef YY_INPUT
#define YY_INPUT(buf, result, max_size) (result = my_yyinput(buf, max_size))
#define EXTERN_C extern "C"
EXTERN_C int
yywrap(void)
{
    return 1;
}
%}
%start C_COMMENT CC_COMMENT STRING_LITERAL_STATE
%%
<INITIAL>"if"           return _If_;
<INITIAL>"else"         return _Else_;
<INITIAL>"elsif"        return _Elseif_;
<INITIAL>"while"        return _While_;
<INITIAL>"for"          return _For_;
<INITIAL>"foreach"      return _Foreach_;
<INITIAL>"return"       return _Return_;
<INITIAL>"break"        return _Break_;
<INITIAL>"continue"     return _Continue_;
<INITIAL>"true"         return _True_;
<INITIAL>"false"        return _False_;
<INITIAL>"try"          return _Try_;
<INITIAL>"catch"        return _Catch_;
<INITIAL>"finally"      return _Finally_;
<INITIAL>"throw"        return _Throw_;
<INITIAL>"bool"			return _Boolean_;
<INITIAL>"int"          return _Int_;
<INITIAL>"double"       return _Double_;
<INITIAL>"string"       return _String_;
<INITIAL>"("            return _Lp_;
<INITIAL>")"            return _Rp_;
<INITIAL>"{"            return _Lc_;
<INITIAL>"}"            return _Rc_;
<INITIAL>";"            return _Semicolon_;
<INITIAL>":"            return _Colon_;
<INITIAL>","            return _Comma_;
<INITIAL>"&&"           return _LogicalAnd_;
<INITIAL>"||"           return _LogicalOr_;
<INITIAL>"="            return _Assign_;
<INITIAL>"=="           return _Eq_;
<INITIAL>"!="           return _Ne_;
<INITIAL>">"            return _Gt_;
<INITIAL>">="           return _Ge_;
<INITIAL>"<"            return _Lt_;
<INITIAL>"<="           return _Le_;
<INITIAL>"+"            return _Add_;
<INITIAL>"-"            return _Sub_;
<INITIAL>"*"            return _Mul_;
<INITIAL>"/"            return _Div_;
<INITIAL>"%"            return _Mod_;
<INITIAL>"+="           return _AddAssign_;
<INITIAL>"-="           return _SubAssign_;
<INITIAL>"*="           return _MulAssign_;
<INITIAL>"/="           return _DivAssign_;
<INITIAL>"%="           return _ModAssign_;
<INITIAL>"++"           return _Increment_;
<INITIAL>"--"           return _Decrement_;
<INITIAL>"!"            return _Exclamation_;
<INITIAL>"."            return _Dot_;

<INITIAL>[A-Za-z_][A-Za-z_0-9]* {
    yylval.identifier  = CreateIdentifier(yytext);
    return _Identifier_;
}
<INITIAL>[1-9][0-9]* {
	Int32 v;
    sscanf(yytext, "%d", &(v));
    yylval.expression  = CreateInt32Expression(v);
    return _IntLiteral_;
}
<INITIAL>"0" {
	Int32 v;
    sscanf(yytext, "%d", &(v));
    yylval.expression  = CreateInt32Expression(v);
    return _IntLiteral_;
}
<INITIAL>[0-9]+\.[0-9]+ {	
	Double v;
    sscanf(yytext, "%lf", &(v));
    yylval.expression  = CreateDoubleExpression(v);
    return _DoubleLiteral_;
}
<INITIAL>\" {
    BEGIN STRING_LITERAL_STATE;
}
<INITIAL>[ \t] ;
<INITIAL>[ \t\r\n] {IncrementLineNumber();}
<INITIAL>"/*"     BEGIN C_COMMENT;
<INITIAL>"//"     BEGIN CC_COMMENT;
<INITIAL>.      {
		char buf[128];
		if (isprint(yytext[0]))
		{
			buf[0] = yytext[0];
			buf[1] = '\0';
		}
		else
		{
			sprintf(buf, "0x%02x", (unsigned char)yytext[0]);
		}
		BadCharError(GetLineNumber(), CreateIdentifier(buf));
}
<C_COMMENT>\n     IncrementLineNumber();
<C_COMMENT>"*/"     {
    BEGIN INITIAL;
}
<C_COMMENT>.      ;
<CC_COMMENT>\n  {
    IncrementLineNumber();
    BEGIN INITIAL;
}
<CC_COMMENT>.   ;
<STRING_LITERAL_STATE>\"        {
    yylval.expression = CreateStringExpression(FlushStringBuffer());
    BEGIN INITIAL;
    return _StringLiteral_;
}
<STRING_LITERAL_STATE>\n        {
    AppendToStringBuffer('\n');
    IncrementLineNumber();	
}
<STRING_LITERAL_STATE>\\\"      AppendToStringBuffer('"');
<STRING_LITERAL_STATE>\\n       AppendToStringBuffer('\n');
<STRING_LITERAL_STATE>\\t       AppendToStringBuffer('\t');
<STRING_LITERAL_STATE>\\\\      AppendToStringBuffer('\\');
<STRING_LITERAL_STATE>.         {
    AppendToStringBuffer(yytext[0]);
}
%%